﻿@using Microsoft.AspNetCore.Html;
@using SimpleIdServer.IdServer.Api.Token.Handlers;
@using SimpleIdServer.IdServer.Website.Resources;
@using SimpleIdServer.IdServer.Website.Stores.ClientStore;
@using SimpleIdServer.IdServer.Website.Stores.IdServerConfigurationStore;
@using SimpleIdServer.IdServer.Website.Stores.ScopeStore;
@using SimpleIdServer.IdServer.Website.Stores.UserStore;
@using SimpleIdServer.IdServer.WsFederation
@using SimpleIdServer.IdServer.WsFederation.Extensions;
@inherits Fluxor.Blazor.Web.Components.FluxorComponent
@inject IDispatcher dispatcher
@inject IState<UpdateClientState> updateClientState
@inject TooltipService tooltipService
@inject NotificationService notificationService

<RadzenTemplateForm Submit=@SubmitUpdateClient TItem="UpdateAdvancedClient" Data=@updateAdvancedClient>
    <RadzenAccordion Multiple=true>    
        <Items>
            <RadzenAccordionItem Text="OpenID configuration" Selected=true>
                <!-- TokenSignedResponseAlg -->
                <div class="row">
                    <div class="col-md-2">
                        <RadzenIcon Icon="info" MouseEnter="@(args => ShowTooltip(args, Global.TokenSignatureAlgTooltip))" />
                        <RadzenLabel Text="@Global.TokenSignatureAlg" Style="padding: 0px;" />
                    </div>
                    <div class="col">
                        <RadzenDropDown Name="TokenSignedResponseAlg" Class="w-100"
                                        Data=@SimpleIdServer.IdServer.Constants.AllSigningAlgs
                                        TValue="string"
                                        @bind-Value=@updateAdvancedClient.TokenSignedResponseAlg />
                    </div>
                </div>
                <!-- IdTokenSignedResponseAlg -->
                <div class="row mt-1">
                    <div class="col-md-2">
                        <RadzenIcon Icon="info" MouseEnter="@(args => ShowTooltip(args, Global.IdTokenSignatureAlgTooltip))" />
                        <RadzenLabel Text="@Global.IdTokenSignatureAlg" Style="padding: 0px;" />
                    </div>
                    <div class="col">
                        <RadzenDropDown Name="IdTokenSignedResponseAlg" Class="w-100"
                                        Data=@SimpleIdServer.IdServer.Constants.AllSigningAlgs
                                        TValue="string"
                                        @bind-Value=@updateAdvancedClient.IdTokenSignedResponseAlg />
                    </div>
                </div>
                <!-- AuthorizationSignedResponseAlg -->
                <div class="row mt-1">
                    <div class="col-md-2">
                        <RadzenIcon Icon="info" MouseEnter="@(args => ShowTooltip(args, Global.AuthorizationResponseSignatureAlgTooltip))" />
                        <RadzenLabel Text="@Global.AuthorizationResponseSignatureAlg" Style="padding: 0px;" />
                    </div>
                    <div class="col">
                        <RadzenDropDown Name="AuthorizationSignedResponseAlg" Class="w-100"
                                        Data=@SimpleIdServer.IdServer.Constants.AllSigningAlgs
                                        TValue="string"
                                        @bind-Value=@updateAdvancedClient.AuthorizationSignedResponseAlg />
                    </div>
                </div>
                <!-- AuthorizationDataTypes -->
                <div class="row mt-1">
                    <div class="col-md-2">
                        <RadzenIcon Icon="info" MouseEnter="@(args => ShowTooltip(args, Global.AuthorizationDataTypesTooltip))" />
                        <RadzenLabel Text="@Global.AuthorizationDataTypes" Style="padding: 0px;" />
                    </div>
                    <div class="col">
                        <RadzenTextBox Name="AuthorizationDataTypes" Class="w-100" @bind-Value=@updateAdvancedClient.AuthorizationDataTypes></RadzenTextBox>
                        <p class="text-muted">@((MarkupString)(Global.AuthorizationDataTypesDescription))</p>
                    </div>
                </div>
                <!-- Response types -->
                <div class="row mt-1">
                    <div class="col-md-2">
                        <RadzenIcon Icon="info" MouseEnter="@(args => ShowTooltip(args, Global.ResponseTypesTooltip))" />
                        <RadzenLabel Text="@Global.ResponseTypes" Style="padding: 0px;" />
                    </div>
                    <div class="col">
                        <RadzenDropDown @bind-Value=@selectedResponseTypes Chips=true Data=@responseTypes Multiple=true AllowClear=true Placeholder="@Global.SelectResponseTypes" class="w-100"></RadzenDropDown>
                    </div>
                </div>
                <!-- Token expiration time -->
                <div class="row mt-1">
                    <div class="col-md-2">
                        <RadzenIcon Icon="info" MouseEnter="@(args => ShowTooltip(args, Global.TokenExpirationTimeTooltip))" />
                        <RadzenLabel Text="@Global.TokenExpirationTime" Style="padding: 0px;" />
                    </div>
                    <div class="col">
                        <RadzenNumeric Name="TokenExpirationTimeInSeconds" Class="w-100" @bind-Value=@updateAdvancedClient.TokenExpirationTimeInSeconds></RadzenNumeric>
                    </div>
                </div>
                <!-- DPoP -->
                <div class="row mt-1">
                    <div class="col-md-2">
                        <RadzenIcon Icon="info" MouseEnter="@(args => ShowTooltip(args, Global.IsDpopRequiredTooltip))" />
                        <RadzenLabel Text="@Global.IsDpopRequired" Style="padding: 0px;" />
                    </div>
                    <div class="col">
                        <RadzenCheckBox @bind-Value="@updateAdvancedClient.IsDPoPRequired" />
                    </div>
                </div>
                <!-- DPoP Nonce -->
                <div class="row mt-1">
                    <div class="col-md-2">
                        <RadzenIcon Icon="info" MouseEnter="@(args => ShowTooltip(args, Global.IsDpopNonceRequiredTooltip))" />
                        <RadzenLabel Text="@Global.IsDpopNonceRequired" Style="padding: 0px;" />
                    </div>
                    <div class="col">
                        <RadzenCheckBox @bind-Value="@updateAdvancedClient.IsDPoPNonceRequired" />
                    </div>
                </div>
                <!-- DPoP Nonce lifetime in seconds -->
                <div class="row mt-1">
                    <div class="col-md-2">
                        <RadzenIcon Icon="info" MouseEnter="@(args => ShowTooltip(args, Global.DpopNonceLifetimeTooltip))" />
                        <RadzenLabel Text="@Global.DpopNonceLifetime" Style="padding: 0px;" />
                    </div>
                    <div class="col">
                        <RadzenNumeric @bind-Value=@updateAdvancedClient.DPOPNonceLifetimeInSeconds Class="w-100" />
                    </div>
                </div>
            </RadzenAccordionItem>
        </Items>
    </RadzenAccordion>

    <RadzenButton class="mt-1" Variant="Variant.Flat" ButtonType="ButtonType.Submit" ButtonStyle="ButtonStyle.Success" Text="@(updateClientState.Value.IsUpdating ? Global.Updating : Global.Update)" Disabled=@updateClientState.Value.IsUpdating />
</RadzenTemplateForm>

@code {
    [Parameter]
    public SimpleIdServer.IdServer.Domains.Client Client { get; set; }

    IEnumerable<string> selectedResponseTypes { get; set; } = new List<string>();
    IEnumerable<string> responseTypes { get; set; } = new List<string>();

    record UpdateAdvancedClient
    {
        public string? TokenSignedResponseAlg { get; set; } = null;
        public string? IdTokenSignedResponseAlg { get; set; } = null;
        public string? AuthorizationSignedResponseAlg { get; set; } = null;
        public string? AuthorizationDataTypes { get; set; } = null;
        public bool IsDPoPRequired { get; set; } = false;
        public bool IsDPoPNonceRequired { get; set; } = false;
        public double DPOPNonceLifetimeInSeconds { get; set; }
        public double TokenExpirationTimeInSeconds { get; set; } = 60 * 30;
    }

    UpdateAdvancedClient updateAdvancedClient = new UpdateAdvancedClient();

    protected override void OnAfterRender(bool firstRender)
    {
        base.OnAfterRender(firstRender);
        if (firstRender)
        {
            SubscribeToAction<GetOpenIdServerConfigurationSuccessAction>((act) =>
            {
                responseTypes = act.Configuration.ResponseTypesSupported.OrderBy(a => a).ToList();
                StateHasChanged();
            });
            SubscribeToAction<UpdateAdvancedClientSettingsSuccessAction>((act) =>
            {
                notificationService.Notify(new NotificationMessage { Severity = NotificationSeverity.Success, Summary = Global.ClientAdvancedSettingsUpdated });
                StateHasChanged();
            });
            SubscribeToAction<UpdateAdvancedClientSettingsFailureAction>((act) =>
            {
                notificationService.Notify(new NotificationMessage { Severity = NotificationSeverity.Error, Summary = act.ErrorMessage });
                StateHasChanged();
            });
            dispatcher.Dispatch(new GetOpenIdServerConfigurationAction());
        }
    }

    protected override void OnParametersSet()
    {
        base.OnParametersSet();
        if (this.Client == null) return;
        updateAdvancedClient = new UpdateAdvancedClient
        {
            TokenSignedResponseAlg = Client.TokenSignedResponseAlg,
            IdTokenSignedResponseAlg = Client.IdTokenSignedResponseAlg,
            AuthorizationSignedResponseAlg = Client.AuthorizationSignedResponseAlg,
            AuthorizationDataTypes = Client.AuthorizationDataTypes == null || !Client.AuthorizationDataTypes.Any() ? string.Empty : string.Join(";", Client.AuthorizationDataTypes),
            IsDPoPRequired = Client.DPOPBoundAccessTokens,
            IsDPoPNonceRequired = Client.IsDPOPNonceRequired,
            DPOPNonceLifetimeInSeconds = Client.DPOPNonceLifetimeInSeconds
        };
        if (Client.TokenExpirationTimeInSeconds != null) 
            updateAdvancedClient.TokenExpirationTimeInSeconds = Client.TokenExpirationTimeInSeconds.Value;
        selectedResponseTypes = Client.ResponseTypes.Where(r => !string.IsNullOrWhiteSpace(r));
    }

    void SubmitUpdateClient(UpdateAdvancedClient client)
    {
        dispatcher.Dispatch(new UpdateAdvancedClientSettingsAction
        {
            AuthorizationDataTypes = client.AuthorizationDataTypes,
            AuthorizationSignedResponseAlg = client.AuthorizationSignedResponseAlg,
            TokenSignedResponseAlg = client.TokenSignedResponseAlg,
            IdTokenSignedResponseAlg = client.IdTokenSignedResponseAlg,
            ResponseTypes = selectedResponseTypes,
            ClientId = Client.ClientId,
            DPOPNonceLifetimeInSeconds = client.DPOPNonceLifetimeInSeconds,
            IsDPoPNonceRequired = client.IsDPoPNonceRequired,
            IsDPoPRequired = client.IsDPoPRequired,
            TokenExpirationTimeInSeconds = client.TokenExpirationTimeInSeconds
        });
    }

    void ShowTooltip(ElementReference eltRef, string msg)
    {
        tooltipService.Open(eltRef, msg, null);
    }
}